#include "proxy_kpabe.h"
#include "string.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

using namespace std;

int main(int argc, char** argv){
	cout << "Hello world" << endl;

	char** attU = (char**)malloc(sizeof(char*));
	attU[0] = "x";
	//owner
	unsigned char *pubBytes, *prvBytes, *userDecBytes, *cipher, *transformedCipher, *mask;
	int pubLen, prvLen, userDecLen, cipherLen, transformedCipherLen, maskLen;

	initOwner(1,attU,1,2, &pubBytes, &pubLen);
	cout << "Done initializing data owner" << endl;
	cout << "TESTING AES" << endl;
	unsigned char *detCipher;
	int detCipherLen;
	enc_det(100,&detCipher,&detCipherLen);
	
	kpabe_pub_t* pub = convertToPubKey(pubBytes, pubLen);
	generateUserDecryptionKey(&userDecBytes, &userDecLen,0);
	generateUserMaskValue(0, &mask, &maskLen);
	cout << "Done initializing decryption key" << endl;
	generateTransformKey("x", &prvBytes, 0, &prvLen);		
	cout << "Done initializing transformation key" << endl;
	char** encAtts = (char**)malloc(sizeof(char*));
	encAtts[0] = "x";
	enc_slidingWindow(encAtts, 1, 124, 2, &cipher, &cipherLen);
	
	cout << "Done encrypting sliding window 1" << endl;	
	unsigned char* cipher1, *transformedCipher1;
	int cipher1Len, transformedCipher1Len;
	enc_slidingWindow(encAtts,1, 73, 3, &cipher1, &cipher1Len);
	
	cout << "Done initializing user and encrypting sliding window" << endl;
	//cloud
	initACInstance(0,pubBytes, pubLen, 0, prvBytes, prvLen);
	transform_simple(cipher, cipherLen,0,0,&transformedCipher, &transformedCipherLen);
	transform_simple(cipher1, cipher1Len, 0, 0, &transformedCipher1,
&transformedCipher1Len);

	GByteArray* buf = convertToByteArray(cipher, cipherLen);
	kpabe_cph_t* cph = kpabe_cph_unserialize(pub, buf, 1);

	buf = convertToByteArray(cipher1, cipher1Len);
	kpabe_cph_t* cph1 = kpabe_cph_unserialize(pub, buf, 1);

	unsigned char* originalCipher = (unsigned char*)malloc(element_length_in_bytes(cph->Ep)*sizeof(char));
	unsigned char* originalCipher1 = (unsigned char*)malloc(element_length_in_bytes(cph1->Ep)*sizeof(char));

	element_to_bytes(originalCipher, cph->Ep);
	element_to_bytes(originalCipher1, cph1->Ep);
	
	unsigned char *ep, *etf;
	int len;

	unsigned char **cpa = (unsigned char**)malloc(sizeof(unsigned char*));
	cpa[0] = transformedCipher;
	cpa[1] = transformedCipher1;
	multiplyCiphers(cpa, 2, 0, &etf, &len);

	cpa[0] = originalCipher;
	cpa[1] = originalCipher1;
	multiplyCiphers(cpa, 2, 0, &ep, &len);	
	//user
	initUser_slidingWindow(pubBytes, pubLen, prvBytes, prvLen, userDecBytes,userDecLen, mask, maskLen,2);
	cout << "Decryption value = " << decrypt_slidingWindow(etf,ep,1) << endl;
	return 0;
}
